\name{JmxModel}
\alias{JmxModel}
\title{Simplify Specifying mxModels}
\description{This function simplifies specifying mxModels by choosing sensible defaults (like making an MxData object from all the manifest variables) and allowing lists of mx objects to be passed.}
\usage{
JmxModel(..., manifestVars, latentVars, data, dtype = c("raw", "cov", "cor"),
  type = "RAM", model = NA, name = NA, run = TRUE, intervals = FALSE)
}
\arguments{
  \item{\dots}{One or more \code{MxPath} objects, or other arguments to be passed to \code{mxModel}.  May also be a list of these objects.}
  \item{manifestVars}{A character vector indicating the manifest variables.  Not required if they are specified in a list passed to \dots.}
  \item{latentVars}{A character vector indicating the latent variables.  Not required if they are specified in a list passed to \dots.}
  \item{data}{A data frame containing the manifest variables.  Not required if and MxData object is passed to \dots.}
  \item{dtype}{The type of MxData object to create (if an MxData object was not passed to \dots).  One of "raw", "cov", or "cor".  Defaults to "raw".}
  \item{type}{The type of model being specified.  Defaults to "RAM".  Note that most the automation only works for RAM models right now.}
  \item{model}{The name of the model.  See \code{?mxModel}}
  \item{name}{The name of the model.  See \code{?mxModel}}
  \item{run}{Logical whether or not to run the model (using \code{mxRun}) or not.  Defaults to \code{TRUE}.}
  \item{intervals}{Logical whether or not to calculate confidence intervals.  Note this is just passed on to \code{mxRun} if the \code{run} argument is set to \code{TRUE}.}
}
\details{Although theoretically this function could work for non RAM type models, I have not tested it with any other type and none of the defaults or automation features were written with any other type in mind.  More details will be forthcoming.}
\value{Most likely a formal "MxRAMModel" object.  If \code{run = TRUE}, it should have all the fitted values.}
\references{\url{http://openmx.psyc.virginia.edu/}}
\author{Joshua Wiley, \url{http://joshuawiley.com/}}
\note{Hopefully I will expand the notes and details soon.}
\section{Warning}{This function is experimental.  Users should be familiar with how to specify MxModels using the regular means before using this function.  This is \emph{not} meant to make using OpenMx more "user friendly", it is meant to save knowledgeable users typing out repetitive lines of code.  Right now there is no error checking built in, so you can easily shoot yourself in the foot.  It is assumed that you are capable of debugging in such cases.}
%\seealso{\code{\link{mxModel}}}
\examples{
##---- Should be DIRECTLY executable !! ----
##-- ==>  Define data, use random,
##--	or do  help(data=index)  for the standard data sets.

## The function is currently defined as
function(..., manifestVars, latentVars, data, dtype = c("raw", "cov", "cor"),
  type = "RAM", model = NA, name = NA, run = TRUE, intervals = FALSE) {
  tmp.args <- list(...)
  new.args <- unlist(tmp.args, recursive = FALSE)

  ## handle manifest variables
  m.index <- grep("manifestVars", names(new.args))
  if (length(m.index) > 0) {
    MVs <- c(unlist(new.args[m.index], recursive = TRUE))
    attributes(MVs) <- NULL
    new.args[m.index] <- NULL
    new.args$manifestVars <- MVs
  }

  if (!missing(manifestVars)) {
    if (any(grepl("manifestVars", names(new.args)))) {
      manifestVars <- c(new.args$manifestVars, manifestVars)
    }
    new.args$manifestVars <- manifestVars
  }

  ## handle latent variables
  l.index <- grep("latentVars", names(new.args))
  if (length(l.index) > 0) {
    LVs <- c(unlist(new.args[l.index], recursive = TRUE))
    attributes(LVs) <- NULL
    new.args[l.index] <- NULL
    new.args$latentVars <- LVs
  }

  if (!missing(latentVars)) {
    if (any(grepl("latentVars", names(new.args)))) {
      latentVars <- c(new.args$latentVars, latentVars)
    }
    new.args$latentVars <- latentVars
  }

  ## Default to RAM model if no type specified
  if (!"type" \%in\% names(new.args)) {
    new.args$type <- type
  }
  if (all(!c("model", "name") \%in\% names(new.args))) {
    new.args$model <- model
    new.args$name <- name
  }

  ## if the data type (dtype) is not specified AND there are no mean paths
  ## use the raw data and set default paths from one to all manifest variables
  if (missing(dtype) && !any(sapply(new.args, function(i) {
    if (inherits(i, "MxPath")) "one" \%in\% i@from else FALSE}))) {
    new.args <- c(new.args, mxPath(from = "one", to = new.args$manifestVars,
      labels = paste("m", new.args$manifestVars, sep = '')))
  }

  ## if no MxData object is supplied create one
  ## defaulting to the raw manifestVars in data
  if (!any(sapply(new.args, function(i) inherits(i, "MxData")))) {
    dtype <- match.arg(dtype)
    data <- data[, new.args$manifestVars]
    new.args <- c(new.args, switch(dtype,
      raw = mxData(observed = data, type = "raw"),
      cov = mxData(observed = cov(na.omit(data)), type = "cov", numObs = nrow(na.omit(data))),
      cor = mxData(observed = cor(na.omit(data)), type = "cor", numObs = nrow(na.omit(data)))
    ))
  }

  M <- do.call("mxModel", new.args)
  if (run) M <- mxRun(M, intervals = intervals)
  return(M)
  }
}
\keyword{misc}
